#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
睡眠脑波数据处理系统 - 日志管理模块

文件功能：
- 统一日志格式管理和输出
- 多文件分类日志记录（原始数据、处理数据、分析结果、系统日志）
- 日志级别控制和文件轮转
- 数据持久化和会话管理

使用方法：
- 创建SleepLogger实例，指定日志目录和文件前缀
- 调用相应的log_*方法记录不同类型的数据
- 支持CSV格式数据导出和系统日志记录

原理：
- 采用分类日志策略，不同类型数据存储在不同文件中
- 使用时间戳和会话ID确保数据可追溯性
- 实现日志文件大小控制和自动轮转机制
"""

import os
import csv
import logging
from datetime import datetime
from typing import Dict, Any, Optional, List
from pathlib import Path


class SleepLogger:
    """
    睡眠监测日志管理器
    
    负责统一管理所有日志输出，包括原始数据、处理数据、分析结果和系统日志
    """
    
    def __init__(self, log_dir: str = "logs", file_prefix: str = "sleep_monitor"):
        """
        初始化日志管理器
        
        Args:
            log_dir: 日志文件存储目录
            file_prefix: 日志文件名前缀
        """
        self.log_dir = Path(log_dir)
        self.file_prefix = file_prefix
        self.session_id = None
        self.log_files = {}
        
        # 创建日志目录
        self.log_dir.mkdir(parents=True, exist_ok=True)
        
        # 初始化系统日志
        self._setup_system_logger()
        
        # 当前会话的CSV写入器
        self.csv_writers = {}
        self.csv_files = {}
    
    def _setup_system_logger(self):
        """
        设置系统日志记录器
        """
        # 创建系统日志文件名
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        log_file = self.log_dir / f"system_log_{timestamp}.log"
        
        # 配置日志格式
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        
        # 创建文件处理器
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        file_handler.setFormatter(formatter)
        
        # 创建控制台处理器
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter)
        
        # 配置日志器
        self.system_logger = logging.getLogger('SleepMonitor')
        self.system_logger.setLevel(logging.INFO)
        self.system_logger.addHandler(file_handler)
        self.system_logger.addHandler(console_handler)
        
        self.system_logger.info(f"日志系统初始化完成，日志目录: {self.log_dir}")
    
    def create_session_log(self, session_id: Optional[str] = None) -> str:
        """
        创建新的会话日志
        
        Args:
            session_id: 会话ID，如果为None则自动生成
            
        Returns:
            str: 会话ID
        """
        if session_id is None:
            session_id = datetime.now().strftime("%Y%m%d_%H%M%S")
        
        self.session_id = session_id
        
        # 关闭之前的CSV文件
        self._close_csv_files()
        
        # 创建新的CSV文件
        self._create_csv_files()
        
        self.system_logger.info(f"创建新会话: {session_id}")
        return session_id
    
    def _create_csv_files(self):
        """
        创建CSV日志文件
        """
        if not self.session_id:
            raise ValueError("请先创建会话")
        
        # 定义CSV文件类型和对应的列名
        csv_configs = {
            'raw_data': ['timestamp', 'session_id', 'eeg_value', 'signal_quality', 'attention', 'meditation'],
            'processed_data': ['timestamp', 'session_id', 'filtered_eeg', 'frequency_bands', 'artifacts_removed'],
            'analysis_results': ['timestamp', 'session_id', 'sleep_stage', 'confidence', 'raw_stage', 'smoothed_stage']
        }
        
        # 创建CSV文件和写入器
        for file_type, columns in csv_configs.items():
            filename = f"{file_type}_{self.session_id}.csv"
            filepath = self.log_dir / filename
            
            # 打开文件
            csv_file = open(filepath, 'w', newline='', encoding='utf-8')
            writer = csv.DictWriter(csv_file, fieldnames=columns)
            writer.writeheader()
            
            # 保存引用
            self.csv_files[file_type] = csv_file
            self.csv_writers[file_type] = writer
            
            self.system_logger.info(f"创建CSV文件: {filename}")
    
    def _close_csv_files(self):
        """
        关闭CSV文件
        """
        for file_type, csv_file in self.csv_files.items():
            if csv_file and not csv_file.closed:
                csv_file.close()
        
        self.csv_files.clear()
        self.csv_writers.clear()
    
    def log_raw_data(self, data: Dict[str, Any], metadata: Optional[Dict[str, Any]] = None):
        """
        记录原始EEG数据
        
        Args:
            data: 原始数据字典，包含eeg_value, signal_quality等
            metadata: 额外的元数据
        """
        if 'raw_data' not in self.csv_writers:
            self.system_logger.warning("原始数据日志文件未初始化")
            return
        
        # 准备日志记录
        log_entry = {
            'timestamp': datetime.now().isoformat(),
            'session_id': self.session_id,
            'eeg_value': data.get('eeg_value', 0),
            'signal_quality': data.get('signal_quality', 0),
            'attention': data.get('attention', 0),
            'meditation': data.get('meditation', 0)
        }
        
        # 写入CSV
        try:
            self.csv_writers['raw_data'].writerow(log_entry)
            self.csv_files['raw_data'].flush()  # 立即写入磁盘
        except Exception as e:
            self.system_logger.error(f"写入原始数据日志失败: {e}")
    
    def log_processed_data(self, data: Dict[str, Any], metadata: Optional[Dict[str, Any]] = None):
        """
        记录预处理后的数据
        
        Args:
            data: 处理后的数据字典
            metadata: 额外的元数据
        """
        if 'processed_data' not in self.csv_writers:
            self.system_logger.warning("处理数据日志文件未初始化")
            return
        
        # 准备日志记录
        log_entry = {
            'timestamp': datetime.now().isoformat(),
            'session_id': self.session_id,
            'filtered_eeg': str(data.get('filtered_eeg', [])),
            'frequency_bands': str(data.get('frequency_bands', {})),
            'artifacts_removed': data.get('artifacts_removed', False)
        }
        
        # 写入CSV
        try:
            self.csv_writers['processed_data'].writerow(log_entry)
            self.csv_files['processed_data'].flush()
        except Exception as e:
            self.system_logger.error(f"写入处理数据日志失败: {e}")
    
    def log_analysis_result(self, result: Dict[str, Any], metadata: Optional[Dict[str, Any]] = None):
        """
        记录睡眠分析结果
        
        Args:
            result: 分析结果字典
            metadata: 额外的元数据
        """
        if 'analysis_results' not in self.csv_writers:
            self.system_logger.warning("分析结果日志文件未初始化")
            return
        
        # 准备日志记录
        log_entry = {
            'timestamp': datetime.now().isoformat(),
            'session_id': self.session_id,
            'sleep_stage': result.get('sleep_stage', 'Unknown'),
            'confidence': result.get('confidence', 0.0),
            'raw_stage': result.get('raw_stage', 'Unknown'),
            'smoothed_stage': result.get('smoothed_stage', 'Unknown')
        }
        
        # 写入CSV
        try:
            self.csv_writers['analysis_results'].writerow(log_entry)
            self.csv_files['analysis_results'].flush()
            
            # 同时记录到系统日志
            self.system_logger.info(
                f"睡眠阶段: {result.get('sleep_stage')} "
                f"(置信度: {result.get('confidence', 0):.2f})"
            )
        except Exception as e:
            self.system_logger.error(f"写入分析结果日志失败: {e}")
    
    def export_logs(self, format_type: str = 'csv', output_dir: Optional[str] = None) -> List[str]:
        """
        导出日志文件
        
        Args:
            format_type: 导出格式，目前支持'csv'
            output_dir: 输出目录，如果为None则使用当前日志目录
            
        Returns:
            List[str]: 导出的文件路径列表
        """
        if format_type != 'csv':
            raise ValueError("目前只支持CSV格式导出")
        
        if output_dir is None:
            output_dir = self.log_dir
        else:
            output_dir = Path(output_dir)
            output_dir.mkdir(parents=True, exist_ok=True)
        
        exported_files = []
        
        # 复制当前会话的CSV文件
        for file_type in ['raw_data', 'processed_data', 'analysis_results']:
            source_file = self.log_dir / f"{file_type}_{self.session_id}.csv"
            if source_file.exists():
                target_file = output_dir / f"exported_{file_type}_{self.session_id}.csv"
                
                # 简单的文件复制
                with open(source_file, 'r', encoding='utf-8') as src:
                    with open(target_file, 'w', encoding='utf-8') as dst:
                        dst.write(src.read())
                
                exported_files.append(str(target_file))
        
        self.system_logger.info(f"导出日志文件到: {output_dir}")
        return exported_files
    
    def get_session_summary(self) -> Dict[str, Any]:
        """
        获取当前会话的摘要信息
        
        Returns:
            Dict[str, Any]: 会话摘要
        """
        if not self.session_id:
            return {}
        
        summary = {
            'session_id': self.session_id,
            'log_dir': str(self.log_dir),
            'files_created': []
        }
        
        # 检查文件是否存在
        for file_type in ['raw_data', 'processed_data', 'analysis_results']:
            filename = f"{file_type}_{self.session_id}.csv"
            filepath = self.log_dir / filename
            if filepath.exists():
                summary['files_created'].append(filename)
        
        return summary
    
    def close(self):
        """
        关闭日志管理器，清理资源
        """
        self._close_csv_files()
        self.system_logger.info("日志管理器已关闭")
        
        # 移除所有处理器
        for handler in self.system_logger.handlers[:]:
            self.system_logger.removeHandler(handler)
            handler.close()


if __name__ == "__main__":
    # 简单测试
    logger = SleepLogger("test_logs")
    
    # 创建会话
    session_id = logger.create_session_log()
    print(f"创建会话: {session_id}")
    
    # 测试日志记录
    logger.log_raw_data({
        'eeg_value': 12345,
        'signal_quality': 0,
        'attention': 50,
        'meditation': 60
    })
    
    logger.log_processed_data({
        'filtered_eeg': [1, 2, 3, 4, 5],
        'frequency_bands': {'delta': 0.1, 'theta': 0.2},
        'artifacts_removed': True
    })
    
    logger.log_analysis_result({
        'sleep_stage': 'N2',
        'confidence': 0.85,
        'raw_stage': 'N1',
        'smoothed_stage': 'N2'
    })
    
    # 获取摘要
    summary = logger.get_session_summary()
    print(f"会话摘要: {summary}")
    
    # 关闭
    logger.close()
    print("测试完成")